package DomainObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import org.omg.PortableServer.POA;

import Combat5.Server;
import ca.etsmtl.log720.lab1.BanqueDossiersPOA;
import ca.etsmtl.log720.lab1.CollectionDossier;
import ca.etsmtl.log720.lab1.CollectionDossierHelper;
import ca.etsmtl.log720.lab1.Dossier;
import ca.etsmtl.log720.lab1.DossierHelper;
import ca.etsmtl.log720.lab1.InvalidIdException;
import ca.etsmtl.log720.lab1.NiveauHorsBornesException;
import ca.etsmtl.log720.lab1.NoPermisExisteDejaException;
//create by martin souliere
public class BanqueDossiersImpl extends BanqueDossiersPOA{
  
	private CollectionDossierImpl _dossiers;
	public BanqueDossiersImpl() throws ClassNotFoundException, IOException{
		try {
			FileInputStream fileInputStream = new FileInputStream("Dossiers.bin");
		    ObjectInputStream objInputStream = new ObjectInputStream(fileInputStream);
		    _dossiers =(CollectionDossierImpl)objInputStream.readObject();
	            objInputStream.close();
		} catch (FileNotFoundException e) {
			_dossiers = new CollectionDossierImpl();
		}
		if(_dossiers == null)
			_dossiers = new CollectionDossierImpl();
	}
	public CollectionDossier dossiers() {
		try {
			// Recuperer le POA cree dans le serveur
			POA rootpoa = Server._poa;

			// Activer l'objet et retourne l'objet CORBA
			org.omg.CORBA.Object obj = rootpoa.servant_to_reference(_dossiers);

			// Retourner une Collection de dossiers
			return CollectionDossierHelper.narrow(obj);
			
		} catch (Exception e) {
			return null;
		}
	}

	public CollectionDossier trouverDossiersParPlaque(String plaque) {
		ArrayList<DossierImpl> listDossiers = new ArrayList<DossierImpl>();
		Dossier current = null;
		for (int i = 0; i < _dossiers.size(); i++) {
			current = _dossiers.getDossier(i);
			if (current.noPlaque().contains(plaque)) {
				listDossiers.add(new DossierImpl(current));
			}
		}	
		return convertCollectionDossierImpl(listDossiers);
	}

	public CollectionDossier trouverDossiersParNom(String nom, String prenom) {
		ArrayList<DossierImpl> listDossiers = new ArrayList<DossierImpl>();
		Dossier current = null;
		for (int i = 0; i < _dossiers.size(); i++) {
			current = _dossiers.getDossier(i);
			if (current.nom().equals(nom) && current.prenom().equals(prenom)) {
				listDossiers.add(new DossierImpl(current));
			}
		}	
		return convertCollectionDossierImpl(listDossiers);
	}

	public Dossier trouverDossierParPermis(String noPermis) {
		for (int i = 0; i < _dossiers.size(); i++) {
			if(_dossiers.getDossier(i).noPermis().equals(noPermis))
			{
				try {
					// Recuperer le POA cree dans le serveur
					POA rootpoa = Server._poa;

					// Activer l'objet et retourne l'objet CORBA
					org.omg.CORBA.Object obj = rootpoa.servant_to_reference(new DossierImpl( _dossiers.getDossier(i)));

					// Retourner un dossier
					return DossierHelper.narrow(obj);
					
				} catch (Exception e) {
					return null;
				}
			}
		}
		return null;
	}

	public Dossier trouverDossierParId(int idDossier) {
		for (int i = 0; i < _dossiers.size(); i++) {
			if(_dossiers.getDossier(i).id() == idDossier)
			{
				try {
					// Recuperer le POA cree dans le serveur
					POA rootpoa = Server._poa;

					// Activer l'objet et retourne l'objet CORBA
					org.omg.CORBA.Object obj = rootpoa.servant_to_reference(new DossierImpl( _dossiers.getDossier(i)));

					// Retourner un dossier
					return DossierHelper.narrow(obj);
					
				} catch (Exception e) {
					return null;
				}
			}
		}
		return null;
	}

	public void ajouterDossier(String nom, String prenom, String noPermis,
			String noPlaque) throws NoPermisExisteDejaException {
		for (int i = 0; i < _dossiers.size(); i++) {
			if(_dossiers.getDossier(i).noPermis().equals(noPermis))
				throw new NoPermisExisteDejaException();
		}
		DossierImpl dossier = new DossierImpl(_dossiers.size() +1,nom,prenom,noPermis,noPlaque);
		_dossiers.getListeDossiers().add(dossier);
		
		save();
	}

	public void ajouterInfractionAuDossier(int idDossier, int idInfraction)
			throws InvalidIdException {
		for (int i = 0; i < _dossiers.size(); i++) {
			if(_dossiers.getDossier(i).id() == idDossier)
			{
				_dossiers.getDossier(i).ajouterInfractionAListe(idInfraction);
				save();
				return;
			}
		}
		throw new InvalidIdException("Impossible de trouver le dossier");
	}

	public void ajouterReactionAuDossier(int idDossier, int idReaction)
			throws InvalidIdException {
		for (int i = 0; i < _dossiers.size(); i++) {
			if(_dossiers.getDossier(i).id() == idDossier)
			{
				_dossiers.getDossier(i).ajouterReactionAListe(idReaction);
				save();
				return;
			}
		}
		throw new InvalidIdException("Impossible de trouver le dossier");
		
	}
	
	private CollectionDossier convertCollectionDossierImpl(ArrayList<DossierImpl> listDossiers)
	{
		CollectionDossierImpl collection = new CollectionDossierImpl(listDossiers);
		try {
			// Recuperer le POA cree dans le serveur
			POA rootpoa = Server._poa;

			// Activer l'objet et retourne l'objet CORBA
			org.omg.CORBA.Object obj = rootpoa.servant_to_reference(collection);

			// Retourner une Collection de dossiers
			return CollectionDossierHelper.narrow(obj);
			
		} catch (Exception e) {
			return null;
		}
	}
	
	///sauvegarde la collection dans une fichier bin pour remplacer la base de données
	private void save()
	{
		try {
			File file = new File("Dossiers.bin");
			if(!file.exists()) {
				file.createNewFile();
			} 
			else
			{
				file.delete();
				file.createNewFile();
			}
			FileOutputStream fileOutPutStream = new FileOutputStream("Dossiers.bin");
			ObjectOutputStream objOutputStream = new ObjectOutputStream(fileOutPutStream);
			objOutputStream.writeObject(_dossiers);
			objOutputStream.flush();
			objOutputStream.close();
		} catch (Exception e) {
			
		}	
	}

}
